#include "LearningFactExtractorWorker.h"

int LearningFactExtractorWorker::parseFolder( Storage &store, string pathToDocuments, string filesFilter ){
	sentenceCount = 0;
	string sConfigFileName = ".\\config.xml";
	std::wstring wsConfigText;
	std::wifstream in( sConfigFileName.c_str() );

	if ( in.fail() ){ 
		cout << "\nCan't open file " << sConfigFileName << '\n';
		status = -1;
	}
	else{
		do {
			wsConfigText += in.get();
			in.peek();
		}
		while( !in.eof() );
		in.close();

		if( (Result = FXCreateContext(wsConfigText.c_str(), &mgr, &hContext)) != FX_SUCCESS )
			status = 1;
	}

	readStopWords();

	_finddata_t fileInfo;

	long find;
	string fileTemplate = pathToDocuments + "*.";
	int findResult = find = _findfirst( fileTemplate.c_str(), &fileInfo );

	while( findResult != -1 ){ 
		if( strcmp( fileInfo.name, ".") && strcmp( fileInfo.name, "..") ){ 

			bool isCluster = true;

			for(unsigned int j = 0; j < strlen(fileInfo.name); j++ ){

				if( fileInfo.name[j] > '9' || fileInfo.name[j] < '0' ){
					isCluster = false;
					break;
				}
			}

			if( isCluster ){
				cout << "Processing cluster: " << fileInfo.name << '\n';
				fileTemplate = pathToDocuments + fileInfo.name + "\\text.txt" ;

				if( parseCluster(store, pathToDocuments + fileInfo.name + "\\", filesFilter, atoi(fileInfo.name) ) )
					status = 1;

				/*
				if( store.clusters.size() > 0 ){
				return 0;
				}
				*/

			}
		}  
		findResult = _findnext( find, &fileInfo );
	}

	if( find != -1 )
		_findclose( find );

	stopWords.clear();

	::FXDestroyContext(hContext);

	store.avgLength /= sentenceCount;

	return status;
}

int LearningFactExtractorWorker::processDocuments( char * clusterText, int &textSize, string pathToDocuments, string filesFilter ){
	_finddata_t fileInfo;

	string fileTemplate = pathToDocuments + filesFilter;
	int findResult, find;
	findResult = find = _findfirst( fileTemplate.c_str(), &fileInfo );

	while( findResult != -1 ){ 
		string filename = pathToDocuments + fileInfo.name;	
		char* fileContent = (char*) malloc( fileInfo.size + 1 );

		if( !fileContent ){
			cout << "\n\n Error memory allocation for file " << filename;
			return -1;
		}

		FILE *f;
		if(  !(f = fopen( filename.c_str(), "rb" )) ){
			cout << "\n\n Error of reading the file " << filename;
			return -1;
		}

		fread( fileContent, fileInfo.size, 1, f );
		fileContent[fileInfo.size] = '\0';
		fclose( f );

		bool found = false, isTag = false;
		unsigned int s = 0, i;
		for(i = 0; i < fileInfo.size; i++){
			if( found ){
				if( fileContent[i] == '<' )
					isTag = true;
				else if( fileContent[i] == '>' )
					isTag = false;
				else if( !isTag && fileContent[i] != '\n' && fileContent[i] != '\r' ){
					clusterText[textSize++] = fileContent[i];
					if( fileContent[i] == '.' && (fileContent[i + 1] == '\n' || fileContent[i + 1] == '\r') ){
						fileContent[i + 1] = ' ';
					}
				}
			}
			else{
				if( fileContent[i] == 'H' )
					s = 1;
				else if( fileContent[i] == 'D' && s == 1 )
					s = 2;
				else if( fileContent[i] == 'R' && s == 2 )
					s = 3;
				else if( fileContent[i] == '>' && s == 3 ){
					found = true;
					clusterText = (char *)realloc(clusterText, textSize + fileInfo.size - i + 1);
				}
				else
					s = 0;
			}
		}
		clusterText[textSize++] = '\n';
		clusterText = (char *)realloc(clusterText, textSize + 1);
		clusterText[textSize] = '\0';
		free(fileContent);
		findResult = _findnext( find, &fileInfo );
	}

	if( find != -1 )
		_findclose( find );

	return 0;
}

int LearningFactExtractorWorker::parseCluster( Storage &store, string pathToDocuments, string filesFilter, int clusterName ){
	_finddata_t fileInfo;
	char *clusterText = (char*) malloc( 1 );
	clusterText[0] = '\0';

	string fileTemplate = pathToDocuments + "text.txt";

	long find;
	int findResult = find = _findfirst( fileTemplate.c_str(), &fileInfo );

	if( findResult != -1 ){
		if( fileInfo.size < 100 ){
			_findclose( find );
			free(clusterText);
			return 0;
		}
		clusterText = (char*) realloc( clusterText, fileInfo.size + 1 );

		if( !clusterText ){
			cout << "\n\n Error memory allocation for file " << fileTemplate;
			return -1;
		}

		FILE *f;
		if( !(f = fopen( fileTemplate.c_str(), "rb")) ){
			cout << "\n\n Error of reading the file " << fileTemplate;
			return -1;
		}

		fread( clusterText, fileInfo.size, 1, f );
		clusterText[fileInfo.size] = '\0';
		fclose(f);

		_findclose( find );
	}
	else{

		int clusterTextSize = 0;

		if( processDocuments( clusterText, clusterTextSize, pathToDocuments + "plus\\", filesFilter ) )
			return -1;

		if( processDocuments( clusterText, clusterTextSize, pathToDocuments + "minus\\", filesFilter ) )
			return -1;

		FILE *f;
		if(  !(f = fopen( fileTemplate.c_str(), "wb" )) ){
			cout << "\n\n Error of writing the file " << fileTemplate;
			return -1;
		}
		fwrite(clusterText, clusterTextSize, 1, f);
		fclose(f);

		if( find != -1 )
			_findclose( find );
	}

	size_t textSize = mbstowcs( NULL, clusterText, 0 );
	wchar_t* fileText = (wchar_t*) malloc((textSize + 1)* sizeof(wchar_t));
	textSize = mbstowcs( fileText, clusterText, textSize );
	fileText[textSize] = 0;

	free( clusterText );

	cout << "Start of processing cluster";
	if( processText( store, fileText, pathToDocuments.c_str(), clusterName ) == -1 )
		return -1;
	cout << " - successfully.\n";

	free( fileText );

	return 0;
}